﻿//-----------------------------------------------------------------------
// <copyright file="SearchPane.cs" company="In The Hand Ltd">
//     Copyright © 2013-14 In The Hand Ltd. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

using System;

#if WINDOWS_PHONE
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Media.Animation;
using Microsoft.Phone.Controls;
#else

using Windows.UI.Popups;
using Windows.ApplicationModel.Resources;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media.Animation;
#endif
using Windows.Foundation;

namespace InTheHand.ApplicationModel.Search
{
    /// <summary>
    /// Represents and manages the search pane that opens when a user activates the Search charm.
    /// The search pane provides a consistent, touch-friendly search box and optional search suggestions.
    /// </summary>
    public sealed class SearchPane
    {
        private static SearchPane instance;

        /// <summary>
        /// Retrieves an instance of the search pane from which users can search within the app.
        /// </summary>
        /// <returns>An instance of the search pane, which provides a consistent, touch-friendly search box and optional search suggestions for searching within the current application.</returns>
        public static SearchPane GetForCurrentView()
        {
            if (instance == null)
            {
                instance = new SearchPane();
            }

            return instance;
        }

        private Popup searchPopup;
        private bool hookedBackKey = false;

        /// <summary>
        /// Fires when the user changes the text in the search box.
        /// </summary>
        [CLSCompliant(false)]
        public event TypedEventHandler<SearchPane, SearchPaneQueryChangedEventArgs> QueryChanged;

        /// <summary>
        /// Fires when the user submits the text in the search box and the app needs to display search results.
        /// </summary>
        [CLSCompliant(false)]
        public event TypedEventHandler<SearchPane, SearchPaneQuerySubmittedEventArgs> QuerySubmitted;

        // <summary>
        // 
        // </summary>
        // event TypedEventHandler<SearchPane, SearchPaneSuggestionsRequestedEventArgs> SuggestionsRequested;

        /// <summary>
        /// Fires when the user opens or closes the search pane.
        /// </summary>
        [CLSCompliant(false)]
        public event TypedEventHandler<SearchPane, SearchPaneVisibilityChangedEventArgs> VisibilityChanged;

        private SearchPane()
        {
            System.Diagnostics.Debug.WriteLine("Created SearchPane");
            searchPopup = new Popup();
            searchPopup.Child = new SearchPanel();
            searchPopup.Opened += searchPopup_Opened;
            searchPopup.Closed += searchPopup_Closed;          
        }

        /// <summary>
        /// The Internet Engineering Task Force (IETF) language tag (BCP 47 standard) that identifies the language currently associated with the user's text input device.
        /// </summary>
        public string Language
        {
            get
            {
                return System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
            }
        }

        /// <summary>
        /// Indicates whether the search pane is open.
        /// </summary>
        /// <value>True if the search pane is being displayed; otherwise false.</value>
        public bool Visible
        {
            get
            {
                return searchPopup.IsOpen;
            }
        }

        /// <summary>
        /// Shows the search pane.
        /// </summary>
        public void Show()
        {
            Show(string.Empty);
        }

        /// <summary>
        /// Shows the search pane with the specified initial query string.
        /// </summary>
        /// <param name="query">The initial query string.</param>
        /// <remarks>If the search pane is already being shown, this function gives focus to the search pane. </remarks>
        public void Show(string query)
        {
            // event must be subscribed to enable search
            if (this.QuerySubmitted != null)
            {
                if (!searchPopup.IsOpen)
                {
                    if (!hookedBackKey)
                    {
#if WINDOWS_PHONE
                        ((Microsoft.Phone.Controls.PhoneApplicationFrame)Application.Current.RootVisual).BackKeyPress += OnBackKeyPress;                      
#else
                        Windows.Phone.UI.Input.HardwareButtons.BackPressed += OnBackKeyPress;
#endif
                        hookedBackKey = true;
                    }


                    FrameworkElement content = searchPopup.Child as FrameworkElement;
#if WINDOWS_PHONE                    
                    Microsoft.Phone.Controls.PhoneApplicationFrame frame = (Microsoft.Phone.Controls.PhoneApplicationFrame)Application.Current.RootVisual;
                    switch (frame.Orientation)
                    {
                        case PageOrientation.LandscapeLeft:
                            SearchPane.GetForCurrentView().Popup.Width = frame.RenderSize.Height - 144;
                            //this.Width = page.ActualWidth;
                            content.RenderTransform = new CompositeTransform() { Rotation = 90, TranslateX = frame.RenderSize.Width, TranslateY = 72 };
                            //this.RenderTransformOrigin = new Point(72, 0);
                            break;
                        case PageOrientation.LandscapeRight:
                            SearchPane.GetForCurrentView().Popup.Width = frame.RenderSize.Height - 144;
                            //this.Width = frame.RenderSize.Height;
                            content.RenderTransform = new CompositeTransform() { Rotation = -90, TranslateY = frame.RenderSize.Height - 72 };
                            break;
                        default:
                            SearchPane.GetForCurrentView().Popup.Width = frame.RenderSize.Width;
                            //this.Width = frame.RenderSize.Width;
                            content.RenderTransform = null;
                            break;
                    }

                    content.Width = searchPopup.Width;
#endif
                    searchPopup.HorizontalAlignment = HorizontalAlignment.Stretch;
                    searchPopup.VerticalAlignment = VerticalAlignment.Stretch;
                    searchPopup.IsOpen = true;
                    ((Storyboard)content.Resources["Show"]).Begin();
                }

                ((SearchPanel)searchPopup.Child).SetFocus();
            }
            else
            {
#if WINDOWS_PHONE
                MessageBox.Show(Resources.Resources.AppCantBeSearched, Resources.Resources.Search.ToUpper(), MessageBoxButton.OK);
#else
                ResourceLoader rl = ResourceLoader.GetForViewIndependentUse("InTheHand.ApplicationModel.Search/Resources");
                MessageDialog md = new MessageDialog(rl.GetString("AppCantBeSearched"), rl.GetString("Search"));
                md.ShowAsync();
#endif
            }
        }

        

        internal Popup Popup
        {
            get
            {
                return searchPopup;
            }
        }

        internal void OnQueryChanged(SearchPaneQueryChangedEventArgs e)
        {
            if (this.QueryChanged != null)
            {
                this.QueryChanged(this, e);
            }
        }

        internal void OnQuerySubmitted(SearchPaneQuerySubmittedEventArgs e)
        {
            if (this.QuerySubmitted != null)
            {
                this.QuerySubmitted(this, e);
            }
        }

        /*internal void OnSuggestionsRequested(SearchPaneSuggestionsRequestedEventArgs e)
        {
            if (this.SuggestionsRequested != null)
            {
                this.SuggestionsRequested(this, e);
            }
        }*/

        internal void OnVisibilityChanged(SearchPaneVisibilityChangedEventArgs e)
        {
            if (this.VisibilityChanged != null)
            {
                this.VisibilityChanged(this, e);
            }
        }

#if WINDOWS_PHONE
        private void searchPopup_Opened(object sender, EventArgs e)
#else
        private void searchPopup_Opened(object sender, object e)
#endif
        {
            OnVisibilityChanged(new SearchPaneVisibilityChangedEventArgs(true));
        }

#if WINDOWS_PHONE
        private void searchPopup_Closed(object sender, EventArgs e)
#else
        private void searchPopup_Closed(object sender, object e)
#endif
        {
            OnVisibilityChanged(new SearchPaneVisibilityChangedEventArgs(false));
        }

#if WINDOWS_PHONE
        private void OnBackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
#else
        private void OnBackKeyPress(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
#endif
        {
            if (searchPopup.IsOpen)
            {
                ((Storyboard)((FrameworkElement)searchPopup.Child).Resources["Hide"]).Begin();
#if WINDOWS_PHONE
                e.Cancel = true;
#else
                e.Handled = true;
#endif
            }
        }
    }
}
